package com.zyl.blog.processing.controller;

import com.zyl.blog.common.response.Result;
import com.zyl.blog.common.domain.file.bean.FileStorage;
import com.zyl.blog.common.domain.file.dto.FileUploadResponse;
import com.zyl.blog.processing.service.FileStorageService;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * 文件存储管理接口
 * @version v1.0
 * @ProjectName: Personal_Blog_Server
 * @Package: com.zyl.blog.processing.controller
 * @ClassName: FileStorageController
 * @Author FinalFantasy
 * @Date 2025/8/15-16:48
 */
@RestController
@RequestMapping("/files")
@RequiredArgsConstructor
public class FileStorageController {

    private final FileStorageService fileStorageService;

    /**
     * 单文件上传
     */
    @PostMapping("/upload")
    public Result<FileUploadResponse> uploadFile(
            @RequestParam("file") MultipartFile file,
            @RequestParam("uploaderId") Long uploaderId,
            @RequestParam(value = "description", required = false) String description
    ) {
        FileUploadResponse response = fileStorageService.uploadFile(file, uploaderId, description);
        return Result.ok(response);
    }

    /**
     * 异步上传文件
     */
    @PostMapping("/upload/async")
    public CompletableFuture<Result<FileUploadResponse>> uploadFileAsync(
            @RequestParam("file") MultipartFile file,
            @RequestParam("uploaderId") Long uploaderId,
            @RequestParam(value = "description", required = false) String description
    ) {
        return fileStorageService.uploadFileAsync(file, uploaderId, description)
                .thenApply(Result::ok);
    }

    /**
     * 批量上传文件
     */
    @PostMapping("/upload/batch")
    public Result<List<FileUploadResponse>> uploadFiles(
            @RequestParam("files") List<MultipartFile> files,
            @RequestParam("uploaderId") Long uploaderId,
            @RequestParam(value = "descriptions", required = false) Map<String, String> descriptions
    ) {
        List<FileUploadResponse> responses = fileStorageService.uploadFiles(files, uploaderId, descriptions);
        return Result.ok(responses);
    }

    /**
     * 下载文件
     */
    @GetMapping("/download/{fileId}")
    public ResponseEntity<Resource> downloadFile(
            @PathVariable("fileId") Long fileId,
            @RequestParam("userId") Long userId
    ) {
        Resource resource = fileStorageService.downloadFile(fileId, userId);
        FileStorage fileInfo = fileStorageService.getFileInfo(fileId);

        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileInfo.getFileName() + "\"")
                .body(resource);
    }

    /**
     * 获取文件信息
     */
    @GetMapping("/{fileId}")
    public Result<FileStorage> getFileInfo(
            @PathVariable("fileId") Long fileId
    ) {

        FileStorage fileInfo = fileStorageService.getFileInfo(fileId);
        return Result.ok(fileInfo);
    }

    /**
     * 删除文件
     */
    @DeleteMapping("/{fileId}")
    public Result<Boolean> deleteFile(
            @PathVariable("fileId") Long fileId,
            @RequestParam("userId") Long userId
    ) {
        boolean result = fileStorageService.deleteFile(fileId, userId);
        return Result.ok(result);
    }

    /**
     * 分页查询文件
     */
    @GetMapping("/list")
    public Result<List<FileStorage>> listFiles(
            @RequestParam("page") int page,
            @RequestParam("size") int size,
            @RequestParam(value = "fileType", required = false) String fileType,
            @RequestParam(value = "uploaderId", required = false) Long uploaderId
    ) {
        List<FileStorage> files = fileStorageService.listFiles(page, size, fileType, uploaderId);
        return Result.ok(files);
    }

    /**
     * 关联文件到指定对象
     */
    @PostMapping("/attach")

    public Result<Boolean> attachFileToEntity(
            @RequestParam("fileId") Long fileId,
            @RequestParam("relationId") Long relationId,
            @RequestParam("relationType") String relationType,
            @RequestParam("isPrimary") boolean isPrimary
    ) {
        boolean result = fileStorageService.attachFileToEntity(fileId, relationId, relationType, isPrimary);
        return Result.ok(result);
    }

    /**
     * 获取对象的所有附件
     */
    @GetMapping("/attachments")
    public Result<List<FileStorage>> getAttachments(
            @RequestParam("relationId") Long relationId,
            @RequestParam("relationType") String relationType
    ) {
        List<FileStorage> attachments = fileStorageService.getAttachments(relationId, relationType);
        return Result.ok(attachments);
    }

    /**
     * 计算文件的MD5哈希值
     */
    @PostMapping("/md5")
    public Result<String> calculateFileMd5(
            @RequestParam("file") MultipartFile file
    ) {
        String md5 = fileStorageService.calculateFileMd5(file);
        return Result.ok(md5);
    }
}

